//
//  CS_MusicTrackModel.swift
//  NewSS
//
//  Created by 杨馥瑞 on 2021/9/9.
//

import UIKit
import HandyJSON

enum LyricType: String, HandyJSONEnum {
    case unknown = ""
    case drc = "drc"        // 逐字
    case lrc = "lrc"        // 逐行
}

struct Lyric: HandyJSON {
    var type = LyricType.unknown
    var url = ""
}

class CS_MusicModel: HandyJSON, Equatable {
    
    required init() {
        
    }
    
    struct Singer: HandyJSON {
        var name = ""
        var photo = ""
    }
    
    struct Audio: HandyJSON {
        var hasFullUrl = false
        var quality = ""
        var length = 0
        var newUrl = ""
        var url = ""
        
        mutating func mapping(mapper: HelpingMapper) {
            mapper <<< hasFullUrl <-- "has_full_url"
            mapper <<< newUrl <-- "new_url"
        }
    }
    
    // 不用作identifier，使用identifier属性作为唯一标识，因为下载的音乐和wifi传输的音乐共用一个模型，下载的音乐有musicTrackId，但是wifi传输的音乐需要自己构建id，构建的方式是通过 singerName+musicName
    var musicTrackId = 0
    var musicName = ""
    var singerName = ""
    var singerPhotoUrl = ""
    var audioUrl = ""
    var audioEncryptUrl = ""
    var audioLength = 0
    /// 歌词相对 url 路径
    var lyricUrl = ""
    var lyricType: LyricType = .unknown
    var sourceDict: [AnyHashable : Any] = [AnyHashable : Any]()
    
    var singer: Singer?
    var audio: Audio?
    var lyric: Lyric?
    
    var isLocal = false
    var isAdded = false {
        didSet {
            addToPlaylistTime = isAdded ? Int(Date().timeIntervalSince1970) : 0
        }
    }
    var createTime = 0
    var modifyTime = 0
    var addToPlaylistTime = 0   // 添加到歌单的时间
    private(set) var displaySingerName = ""
    
    /// 真正用于标识唯一性的字段
    var identifier = ""
    
    func mapping(mapper: HelpingMapper) {
        mapper <<< musicName <-- ["name", "musicName"]
        mapper <<< musicTrackId <-- ["musicTrackId", "id"]
        mapper <<< singerName <-- ["singer.name", "singerName"]
        mapper <<< singerPhotoUrl <-- ["singer.photo", "singerPhotoUrl"]
        mapper <<< audioUrl <-- ["audio.url", "audioUrl"]
        mapper <<< audioEncryptUrl <-- ["audio.new_url", "audioEncryptUrl"]
        mapper <<< audioLength <-- ["audio.length", "audioLength"]
        mapper <<< lyricUrl <-- ["lyric.url", "lyricUrl"]
        mapper <<< lyricType <-- ["lyric.type", "lyricType"]
    }
    
    func getIdentifier() -> String {
        return isLocal ? singerName + "_" + musicName : String(musicTrackId)
    }
    
    static func == (lhs: CS_MusicModel, rhs: CS_MusicModel) -> Bool {
        return lhs.identifier == rhs.identifier
    }
    
    var filePath: String {
        func getImportFromWifiMusicLocalFilePath() -> String {
            return CS_MusicWifiFileStorage.shared.getAbsoluteFilePath(musicName)
        }
        func getImportFromServerMusicLocalFilePath() -> String {
            return CS_AccompanyManager.shardInstance.getAudioLocalPath(from: self)
        }
        return isLocal ? getImportFromWifiMusicLocalFilePath() : getImportFromServerMusicLocalFilePath()
    }
    
    // 存储文件时，使用的文件名
    func getCahceFileName() -> String {
        return isLocal ? musicName : musicName + "\(musicTrackId)"
    }

    var fileExist: Bool {
        if !isLocal {
            return CS_ImportMusicRequest.musicIsDownloaded(self)
        }
        return FileManager.default.fileExists(atPath: filePath)
    }
    
    var properUrlForUsed: String {
        return audioEncryptUrl.isEmpty ? audioUrl : audioEncryptUrl
    }
    
    static func getMusicModelWithDict(_ dict: [String : Any]?) -> CS_MusicModel? {
        guard let dict = dict else { return nil }
        let result = CS_MusicModel.deserialize(from: dict)
        result?.sourceDict = dict
        return result
    }
    
//    static func deserializeFromDB(_ dict: [String : Any]?) -> CS_MusicModel? {
//
//    }

//    static func queryMusicForFileExists() -> [CS_MusicModel] {
//
//    }
//
//
//    static func musicDocumentPathWithKey(_ key: String) -> String {
//
//    }
//
//    func removeFromFile() -> Bool {
//
//    }
}
